package com.kakaxi.mybilibili.base;

import android.app.Activity;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewParent;

import java.util.Iterator;
import java.util.Map;

/**
 * 基础侧滑视图活动类
 * 提供了一些使用侧滑视图的方法
 * Created by kakaxi on 16/8/8.
 */
public abstract class BaseNavigationActivity extends BaseActivity {

    /** 侧滑布局用来调用关闭侧滑视图 **/
    private DrawerLayout mDrawerLayout;

    /** 侧滑视图 **/
    private NavigationView mNavigationView;

    /** 侧滑视图点击监听器 **/
    private NavigationView.OnNavigationItemSelectedListener mNavigationListener;

    /** 碎片键值数组 **/
    private Map<Integer, Fragment> mMenuFragmentMap;

    /** 活动键值数组 **/
    private Map<Integer, ItemActivityBean> mMenuActivityMap;

    /** 碎片替换的控件布局的字符串id **/
    private String mReplaceIdStr = "flayout_content";
    /** 碎片替换的控件布局id **/
    private int mReplaceId;

    /** 侧滑视图的顶部布局的跳转活动数组 **/
    private Map<Integer, Activity> mHeaderActivityMap;

    /** 当前选中的菜单 **/
    private MenuItem mCurrentCheckedItem;

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);

        // 获取侧滑布局,判断侧滑视图的父视图是否为侧滑布局
        ViewParent parent = mNavigationView.getParent();
        if (parent instanceof DrawerLayout) {
            mDrawerLayout = (DrawerLayout) parent;
        }

        // 通过子类填入的id获取侧滑视图
        mNavigationView = (NavigationView) findViewById(getNavgationViewId());
        if (mNavigationView != null) { // 侧滑视图不为空
            // 设置侧滑视图的监听器
            if (mNavigationListener != null) {
                // 自定义的监听处理
                mNavigationView.setNavigationItemSelectedListener(mNavigationListener);
            } else {
                // 默认的监听处理
                mNavigationView.setNavigationItemSelectedListener(new NavigationView
                        .OnNavigationItemSelectedListener() {

                    @Override
                    public boolean onNavigationItemSelected(MenuItem item) {
                        if (mDrawerLayout != null) { // 关闭侧滑视图
                            mDrawerLayout.closeDrawer(mNavigationView);
                        }

                        if (item.getItemId() == mCurrentCheckedItem.getItemId()) {
                            return false;
                        }

                        if (mMenuActivityMap != null) { // 活动跳转
                            ItemActivityBean toActivity = mMenuActivityMap.get(item.getItemId());
                            if (toActivity != null && toActivity.getActivity() != null) {
                                // 活动跳转不需要返回true, 因为每个活动都有自己的侧滑视图
                                goActivity(toActivity.getActivity().getClass());
                                return false;
                            }
                        }
                        if (mMenuFragmentMap != null) { // 碎片跳转
                            Fragment toFragment = mMenuFragmentMap.get(item.getItemId());
                            if (toFragment != null) {
                                // 如果替换的id是0的话,使用默认的id
                                if (mReplaceId == 0) {
                                    mReplaceId = getResources().getIdentifier(mReplaceIdStr, "id",
                                            getPackageName());
                                }
                                if (mReplaceId != 0) {
                                    // 替换碎片,并把所点的菜单项设置为选中
                                    getSupportFragmentManager().beginTransaction().replace
                                            (mReplaceId, toFragment).commit();
                                    return true;
                                }
                            }
                        }

                        // 上面没做跳转操作, 最后就会调用其他操作方法
                        return menuOtherAction(item);
                    }
                });

                // 设置顶部布局的监听器
                if (mHeaderActivityMap != null) {
                    // 使用迭代器 循环拿出数组中的id以及对应的跳转活动,对控件设置点击监听器
                    Iterator<Integer> keysIt = mHeaderActivityMap.keySet().iterator();
                    while (keysIt.hasNext()) {
                        // key为控件的id
                        Integer key = keysIt.next();
                        final Activity goActivity = mHeaderActivityMap.get(key);
                        View view = findViewById(key);
                        if (view != null && goActivity != null) {
                            view.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    // 跳转到对应活动
                                    goActivity(goActivity.getClass());
                                }
                            });
                        }
                    }
                }


            }
        }
    }

    /**
     * 这个方法填写侧滑视图的id
     */
    protected abstract int getNavgationViewId();

    /**
     * 侧滑视图默认监听器中调用这个方法来处理除了跳转以外的自定义操作(例如夜间模式)
     *
     * @return 是否选中所点击的菜单, 如不需任何其他操作返回fasle
     */
    protected abstract boolean menuOtherAction(MenuItem item);

    /**
     * 获取侧滑视图
     *
     * @return
     */
    protected NavigationView getNavigationView() {
        return mNavigationView;
    }

    /**
     * 返回侧滑视图的头视图,以便可以自定义
     *
     * @return
     */
    protected View getHeaderView() {
        return mNavigationView.getHeaderView(0);
    }


    /**
     * 设置侧滑视图监听器
     *
     * @param navigationListener 侧滑视图监听器
     */
    protected void setNavigationItemSelectedListener(NavigationView
                                                             .OnNavigationItemSelectedListener
                                                             navigationListener) {
        if (navigationListener != null) {
            mNavigationListener = navigationListener;
        }
    }

    /**
     * 设置碎片数组对应侧滑视图上所点击的菜单,键对应的是菜单id,值对应的是要跳转的碎片
     *
     * @param fragmentMap 侧滑视图的碎片数组
     * @param replaceId   替换id
     */
    protected void setNavigationMenuFragmentMap(Map<Integer, Fragment> fragmentMap, int replaceId) {
        if (fragmentMap != null) {
            mMenuFragmentMap = fragmentMap;

            // 检查id是否存在
            if (findViewById(replaceId) != null) {
                mReplaceId = replaceId;
            }
        }
    }

    /**
     * 设置碎片数组对应侧滑视图上所点击的菜单,键对应的是菜单id,值对应的是要跳转的碎片
     *
     * @param fragmentMap 侧滑视图的碎片数组
     */
    protected void setNavigationMenuFragmentMap(Map<Integer, Fragment> fragmentMap) {
        this.setNavigationMenuFragmentMap(fragmentMap, 0);
    }

    /**
     * 获取碎片数组
     */
    protected Map<Integer, Fragment> getNavigationMenuFragmentMap() {
        return mMenuFragmentMap;
    }

    /**
     * 获取替换id
     *
     * @return
     */
    protected int getReplaceId() {
        return mReplaceId;
    }

    /**
     * 设置活动数组对应侧滑视图上所点击的菜单,键对应的是菜单id,值对应的是要跳转的活动
     *
     * @param activityMap
     */
    protected void setNavigationMenuActivityMap(Map<Integer, ItemActivityBean> activityMap) {
        if (activityMap != null) {
            mMenuActivityMap = activityMap;
        }
    }

    /**
     * 获取活动数组
     *
     * @return
     */
    protected Map<Integer, ItemActivityBean> getNavigationMenuActivityMap() {
        return mMenuActivityMap;
    }

    /**
     * 设置顶部布局控件所对应的跳转活动数组
     *
     * @param activityMap
     */
    protected void setNavigationHeaderActivityMap(Map<Integer, Activity> activityMap) {
        if (activityMap != null) {
            mHeaderActivityMap = activityMap;
        }
    }

    /**
     * 获取顶部布局的控件所对应的跳转活动数组
     *
     * @return
     */
    protected Map<Integer, Activity> getNavigationHeaderActivityMap() {
        return mHeaderActivityMap;
    }

    /**
     * 跳转活动信息, 参数包括了活动和是否关闭上一个活动
     */
    class ItemActivityBean {

        private Activity activity;

        private boolean finish;

        public ItemActivityBean(Activity activity) {
            this.activity = activity;
        }

        public ItemActivityBean(Activity activity, boolean finish) {
            this.activity = activity;
            this.finish = finish;
        }

        public Activity getActivity() {
            return activity;
        }

        public void setActivity(Activity activity) {
            this.activity = activity;
        }

        public boolean isFinish() {
            return finish;
        }

        public void setFinish(boolean finish) {
            this.finish = finish;
        }
    }

}
